/**
* HTTPUtil.java
*
* This program is distributed under the terms of the GNU General Public
* License
* Copyright 2008 NJ Pearman
*
* This file is part of MobScrob.
*
* MobScrob is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* MobScrob is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with MobScrob. If not, see <http://www.gnu.org/licenses/>.
*/
package mobscrob.util.microedition;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Vector;
import javax.microedition.io.Connector;
import javax.microedition.io.HttpConnection;
import mobscrob.logging.Log;
import mobscrob.logging.LogFactory;
/**
* @author Neill
*
*/
public class HTTPUtil {
private static final Log log = LogFactory.getLogger(HTTPUtil.class);
private static final String ENC_UTF8 = "UTF-8";
public static final String HEADER_HOST = "Host";
private HTTPUtil() {}
/**
* Encodes a parameter, also ensuring that it is UTF-8
*
* @param s
* @return
* @throws UnsupportedEncodingException
*/
public static String encodeParam(String s)
throws UnsupportedEncodingException {
if (s == null) {
return s;
}
// encode as UTF-8
String utf8Str = new String(s.getBytes(), ENC_UTF8);
StringBuffer sb = new StringBuffer(utf8Str.length() * 3);
char[] chars = utf8Str.toCharArray();
int next;
// encode the chars in the UTF-8 String
for (int i = 0; i < chars.length; i++) {
next = chars[i];
if ((next >= 0x30 && next <= 0x39) || // 0-9
(next >= 0x41 && next <= 0x5A) || // A-Z
(next >= 0x61 && next <= 0x7A)) { // a-z
sb.append((char) next);
} else if ((next == 0xA0)) { // ' ' (whitespace)
sb.append('+');
} else { // encode all other chars
sb.append("%");
if (next <= 0xf)
sb.append("0");
sb.append(Integer.toHexString(next));
}
}
return sb.toString();
}
/**
* Attempts to open a URL using the GET method over HTTP and read the
* response into a byte array. Any IOExceptions are simply thrown out of
* this method to be caught elsewhere.
*
* @param url
* @return
* @throws IOException
*/
public static byte[] getUrl(String url, String headerHostname) throws IOException {
HttpConnection conn = null;
try {
conn = (HttpConnection) Connector.open(url);
// set the compulsory HTTP/1.1 Host: header, as GET
conn.setRequestMethod(HttpConnection.GET);
conn.setRequestProperty(HEADER_HOST, headerHostname);
byte[] body = readHttpResponse(conn);
return body;
} finally {
closeHttpConnection(conn);
}
}
/**
* Reads the response from the specified HTTP connection into a byte array.
*
* @param conn
* @return
* @throws IOException
*/
public static byte[] readHttpResponse(HttpConnection conn) throws IOException {
final String methodName = "6";
int rc = conn.getResponseCode();
if (rc != HttpConnection.HTTP_OK) {
String msg = "HTTP response code not OK: " + rc;
log.info(methodName, msg);
throw new IOException(msg);
} else {
log.info(methodName, "Response is HTTP OK");
}
String connHeader = conn.getHeaderField("Connection");
log.info(methodName, "HTTP response Connection header: " + connHeader);
// connect
int len = (int) conn.getLength();
log.info(methodName, "Got content length: " + len);
InputStream is = null;
try {
is = conn.openInputStream();
// read response
if (len > -1) {
log.info(methodName, "Reading into byte array");
byte[] body = new byte[len];
int actual = 0;
int bytesread = 0;
while ((bytesread != len) && (actual != -1)) {
actual = is.read(body, bytesread, len - bytesread);
bytesread += actual;
}
// do something
log.info(methodName, "Finished reading HTTP stream");
return body;
} else {
// read byte by byte...?
log.error(methodName, "Body length zero, reading bytes");
Vector bytes = new Vector();
Byte byteObj;
int next;
while ((next = is.read()) > -1) {
byteObj = new Byte((byte) next);
bytes.addElement(byteObj);
}
log.info(methodName, "Read body, length " + bytes.size());
byte[] body = new byte[bytes.size()];
Enumeration e = bytes.elements();
int i = 0;
while (e.hasMoreElements()) {
byteObj = (Byte) e.nextElement();
body[i++] = byteObj.byteValue();
}
return body;
}
} finally {
if (is != null) {
try {
is.close();
} catch (Exception e) {
log.error(methodName, "Unable to close HTTP input stream: "
+ e.getMessage(), e);
}
}
}
}
public static void closeHttpConnection(HttpConnection conn) {
final String methodName = "7";
if (conn != null) {
try { conn.close(); }
catch (Exception e) { log.error(methodName, "Unable to close HTTP connecton: " + e.getMessage(), e); }
}
}
}